package com.credithc.eagleeye.api.utils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.EntityBuilder;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
/**
 * 描 述: <br/>
 * 作 者: zhangjin<br/>
 * 创 建：2017年04月22日<br/>
 * 版 本：v1.0.0<br>
 * <p>
 * 历 史: (版本) 作者 时间 注释 <br/>
 */
public class HttpClientUtil {
    private static CloseableHttpClient httpClient;
    static {
        LayeredConnectionSocketFactory sslFactory = null;
        try {
            sslFactory = new SSLConnectionSocketFactory(SSLContext.getDefault());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("https", sslFactory)
                .register("http", new PlainConnectionSocketFactory())
                .build();
        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
        cm.setMaxTotal(2000);
        cm.setDefaultMaxPerRoute(500);
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(5 * 1000).setConnectTimeout(3 * 1000).build();

        // 请求重试处理
        HttpRequestRetryHandler httpRequestRetryHandler = new DefaultHttpRequestRetryHandler(1,false);
        httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig).setRetryHandler(httpRequestRetryHandler).setConnectionManager(cm).build();

    }
    private static CloseableHttpClient getHttpClient() {
        return httpClient;
    }
    private HttpClientUtil() {
    }
    public static String get(String requestUrl, Map<String, String> paramsMap, String encoding) throws IOException {
        String url = requestUrl;
        String params = "rnd=" + new Random().nextInt();
        for(Map.Entry<String, String> entry : paramsMap.entrySet()) {
            params += "&" + entry.getKey() + "=" + entry.getValue();
        }
        if (!requestUrl.contains("?")) {
            url = url + "?";
        } else {
            if (requestUrl.contains("&")) {
                params = "&" + params;
            }
        }
        return get(url + params, encoding);
    }
    public static String get(String requestUrl, String paramsStr, String encoding) throws IOException {
        return get(requestUrl + paramsStr, encoding);
    }
    public static String get(String requestUrl, String encoding) throws IOException {
        String result = null;
        CloseableHttpResponse httpResponse = null;
        try {
            HttpGet HttpGet = new HttpGet(requestUrl);
            httpResponse = getHttpClient().execute(HttpGet);
            HttpEntity entity = httpResponse.getEntity();
            result = EntityUtils.toString(entity, encoding);
            EntityUtils.consume(entity);
        } finally {
            if (httpResponse != null) {
                httpResponse.close();
            }
        }
        return result;
    }
    public static String postJson(String requestUrl, String requestContent, String encoding) throws IOException {
        StringEntity requestEntity = new StringEntity(requestContent, encoding);
        requestEntity.setContentEncoding(encoding);
        requestEntity.setContentType("application/json");
        return post(requestUrl, requestEntity, encoding);
    }
    public static String post(String requestUrl, String requestContent, String encoding) throws IOException {
        StringEntity requestEntity = new StringEntity(requestContent);
        return post(requestUrl, requestEntity, encoding);
    }
    public static String post(String requestUrl, Map<String, String> params, String encoding) throws IOException {
        return post(requestUrl, transMap2HttpEntity(params, encoding), encoding);
    }
    public static String post(String requestUrl, HttpEntity httpEntity, String encoding) throws IOException {
        String result = null;
        CloseableHttpResponse httpResponse = null;
        try {
            HttpPost httpPost = new HttpPost(requestUrl);
            httpPost.setEntity(httpEntity);
            httpResponse = getHttpClient().execute(httpPost);
            result = EntityUtils.toString(httpResponse.getEntity(), encoding);
            EntityUtils.consume(httpResponse.getEntity());
        } finally {
            if (httpResponse != null) {
                httpResponse.close();
            }
        }
        return result;
    }
    private static HttpEntity transMap2HttpEntity(Map<String, String> params, String encoding) throws UnsupportedEncodingException {
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        if (params != null) {
            for(Map.Entry<String, String> entry : params.entrySet()) {
                nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
            }
        }
        EntityBuilder builder = EntityBuilder.create();
        builder.setParameters(nvps);
        return new UrlEncodedFormEntity(nvps, encoding);
    }
}
